from aip import AipSpeech
from django.conf import settings
import logging
import os
import subprocess
import tempfile

logger = logging.getLogger(__name__)

class BaiduSpeechRecognizer:
    def __init__(self):
        config = settings.BAIDU_SPEECH_CONFIG
        logger.debug(f"初始化百度语音识别，APP_ID: {config['APP_ID']}")
        self.client = AipSpeech(config['APP_ID'], config['API_KEY'], config['SECRET_KEY'])
    
    def convert_audio_to_wav(self, input_path, output_path):
        """使用ffmpeg转换音频格式到WAV"""
        logger.debug(f"开始转换音频格式: {input_path} -> {output_path}")
        try:
            cmd = [
                'ffmpeg', '-i', input_path, 
                '-ar', '16000',
                '-ac', '1',
                '-y',
                output_path
            ]
            result = subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            logger.debug("音频格式转换成功")
            return True
        except subprocess.CalledProcessError as e:
            logger.error(f"音频转换失败，错误: {e.stderr.decode()}")
            return False
        except FileNotFoundError:
            logger.error("ffmpeg未安装，无法转换音频格式")
            return False
    
    def recognize_audio_file(self, audio_file_path, original_format=None):
        """识别音频文件"""
        logger.debug(f"开始识别音频文件: {audio_file_path}, 格式: {original_format}")
        
        try:
            if original_format:
                file_ext = original_format.lower()
            else:
                file_ext = os.path.splitext(audio_file_path)[1].lower().lstrip('.')
            
            logger.debug(f"检测到文件格式: {file_ext}")
            
            # 如果是WAV或PCM格式，直接识别
            if file_ext in ['wav', 'pcm']:
                logger.debug("直接识别WAV/PCM文件")
                with open(audio_file_path, 'rb') as audio_file:
                    audio_data = audio_file.read()
                return self._recognize_audio(audio_data, 'wav')
            
            # 其他格式需要转换
            else:
                logger.debug(f"需要转换格式: {file_ext} -> wav")
                with tempfile.NamedTemporaryFile(suffix='.wav', delete=False) as temp_wav:
                    temp_wav_path = temp_wav.name
                
                logger.debug(f"创建临时文件: {temp_wav_path}")
                
                if self.convert_audio_to_wav(audio_file_path, temp_wav_path):
                    with open(temp_wav_path, 'rb') as audio_file:
                        audio_data = audio_file.read()
                    logger.debug("开始识别转换后的音频")
                    result = self._recognize_audio(audio_data, 'wav')
                    
                    # 清理临时文件
                    try:
                        os.unlink(temp_wav_path)
                        logger.debug("清理临时文件完成")
                    except:
                        logger.warning("清理临时文件失败")
                    return result
                else:
                    logger.error("音频格式转换失败")
                    return False, "音频格式转换失败"
                    
        except Exception as e:
            logger.error(f"语音识别异常: {e}", exc_info=True)
            return False, f"识别异常: {str(e)}"
    
    def _recognize_audio(self, audio_data, format='wav', rate=16000, dev_pid=1537):
        """内部识别方法"""
        try:
            logger.debug(f"发送音频数据到百度API，长度: {len(audio_data)} bytes")
            result = self.client.asr(audio_data, format, rate, {
                'dev_pid': dev_pid,
            })
            
            logger.debug(f"百度API返回: {result}")
            
            if result.get('err_no') == 0:
                recognized_text = result['result'][0] if result['result'] else ""
                logger.debug(f"语音识别成功: '{recognized_text}'")
                return True, recognized_text
            else:
                error_msg = f"识别错误: {result.get('err_msg', '未知错误')}, 错误码: {result.get('err_no')}"
                logger.error(f"语音识别失败: {error_msg}")
                return False, error_msg
                
        except Exception as e:
            logger.error(f"语音识别异常: {e}", exc_info=True)
            return False, f"识别异常: {str(e)}"

# 全局实例
speech_recognizer = BaiduSpeechRecognizer()